home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK1.toast / Development Kits (Disc 1) / AppleScript / Development Tools / Sample Code / Æ Coercion / Coercions.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-19  |  5.6 KB  |  144 lines  |  [TEXT/MPS ]

  1. /*------------------------------------------------------------------------------
  2. *
  3. *  Apple Developer Technical Support
  4. *
  5. *  AppleEvent Coercion Handler and INIT sample
  6. *
  7. *  Program:    AECoercionINIT
  8. *  File: Coercions.c -    C Source
  9. *
  10. *  by:   C.K. Haun <TR>
  11. *
  12. *  Copyright © 1991 Apple Computer, Inc.
  13. *  All rights reserved.
  14. *
  15. *------------------------------------------------------------------------------
  16. *   This file contains the actual coercion routines, which will be BlockMoved
  17. *   into the System Heap and installed as System Level coercions
  18. *   at INIT time
  19. *------------------------------------------------------------------------------
  20. */
  21. /* Our includes */
  22. #include <Types.h>
  23. #include <memory.h>
  24. #include <Errors.h>
  25. #include <AppleEvents.h> 
  26.  
  27. #define typeMyPString 'MPST'    
  28.  
  29. /* A structure I use in my Boolean to Char coercion */
  30. struct myBtoCData {
  31.     Handle falseString;
  32.     Handle trueString;
  33. };
  34. typedef struct myBtoCData myBtoCData, *myBtoCDataPtr, **myBtoCDataHdl;
  35.  
  36. /* These first two routines coerce a PString to typeChar and back */
  37. /* they work on a typeMyPString, which I made up for this example */
  38. /* For this example, I created a typePString.  A typePString would be... */
  39. /* descriptorType = 'MPST' 
  40. dataHandle = (handle containing a Pascal-type string) */
  41. pascal OSErr CoerceCharToPString(DescType origData, Ptr inPtr, Size theSize, DescType toType, long refCon, AEDesc *result)
  42. {
  43. #pragma unused (refCon)
  44.     OSErr myErr = noErr;
  45.     Str255 theString;
  46.     Size newSize;
  47.     /* This check isn't really necessary, since the AEM won't call you  */
  48.     /* if the data types don't match, but I wanted to used the parameters */
  49.     /* see the Note at the end of this file for what you Can use these for */
  50.     if ((origData == typeChar) && (toType == typeMyPString)) {
  51.         /* first make sure the char block isn't over a PString size.  If it is, I'll */
  52.         /* truncate it to a PString and continue */
  53.         if (theSize > 255)
  54.             newSize = 255;
  55.         else
  56.             newSize = theSize;
  57.         theString[0] = newSize;
  58.         /* Move what we were given into my string */
  59.         BlockMove(inPtr, (Ptr)&theString[1], newSize);
  60.         /* Make an AppleEvent descriptor out of it */
  61.         myErr = AECreateDesc(typeMyPString, (Ptr)&theString[0], theString[0] + 1, result);
  62.     } else {
  63.         myErr = errAECoercionFail;
  64.     }
  65.     return(myErr);
  66. }
  67.  
  68. pascal OSErr CoercePStringToChar(DescType origData, Ptr inPtr, Size theSize, DescType toType, long refCon, AEDesc *result)
  69. {
  70. #pragma unused (origData,toType,refCon)
  71.     OSErr myErr = noErr;
  72.     /* This check isn't really necessary, since the AEM won't call you  */
  73.     /* if the data types don't match, but I wanted to used the parameters */
  74.     /* see the Note at the end of this file for what you Can use these for */
  75.     if ((origData == typeMyPString) && (toType == typeChar)) {
  76.         /* Don't have to worry about the size here, since a typeChar can be much larger */
  77.         /* than a PString, just make the desriptor */
  78.         myErr = AECreateDesc(typeChar, (Ptr)(inPtr + 1), theSize - 1, result);
  79.     } else {
  80.         myErr = errAECoercionFail;
  81.     }
  82.     return(myErr);
  83. }
  84.  
  85. /*  CoerceBooleanToChar creates a desc that says True or False. */
  86. /* nice for human (well, non-programmer) reading */
  87. /* NOTE:  This coercion uses the refCon field to hold a handle */
  88. pascal OSErr CoerceBooleanToChar(DescType origData, Ptr inPtr, Size theSize, DescType toType, long refCon, AEDesc *result)
  89. {
  90.     
  91.     OSErr myErr = noErr;
  92.     /* Our string data is in our refCon, (see the Install routine) */
  93.     /* so coerce it to something we can work with */
  94.     myBtoCDataHdl myStrings = (myBtoCDataHdl)refCon;
  95.     /* make sure everything is fine first */
  96.     if (origData != typeBoolean || toType != typeChar) {
  97.         /* something is goofy here */
  98.         myErr = errAECoercionFail;
  99.     } else {
  100.         /* a boolean should be two bytes. if it isn't, I'm confused */
  101.         if (theSize == sizeof(short)) {
  102.             Ptr theText;
  103.             short theBool = *((short *)inPtr);
  104.             HLock((Handle)myStrings);
  105.             /* I'm locking both of these even though I'll only use one */
  106.             /* You can count cycles and see if doing two compares (before and after) */
  107.             /* and one lock/unlock is faster, but I don't think it matters much */
  108.             HLock((*myStrings)->falseString);
  109.             HLock((*myStrings)->trueString);
  110.             /* decide which string we're using */
  111.             if (theBool)
  112.                 theText = *((*myStrings)->trueString);
  113.             else
  114.                 theText = *((*myStrings)->falseString);
  115.             /* And make a descriptor */
  116.             myErr = AECreateDesc(typeChar, (theText + 1), *theText, result);
  117.             HUnlock((*myStrings)->falseString);
  118.             HUnlock((*myStrings)->trueString);
  119.             HUnlock((Handle)myStrings);
  120.         } else {
  121.             myErr = errAECoercionFail;
  122.         }
  123.     }
  124.     return(myErr);
  125. }
  126.  
  127.  
  128.  
  129. /* Dummy is just a placemarker so I know where the end of  is.  I could  */
  130. /* have done that a different way, but this left me some flexibility */
  131. void Dummy(void)
  132. {
  133. }
  134.  
  135. /* ••• Note:  The AEM always passes the fromType and toType to your coercion */
  136. /* routines.  Why?  You know you're not going to be called if the types aren't */
  137. /* correct, so why bother? */
  138. /* THe reason is to allow you to put all your coercions in one big function. */
  139. /* You can case off them, and do everything you want in one place, instead of */
  140. /* in scattered routines. */
  141. /* I am _not_ doing this in this example, because I'm grabbing memory from the  */
  142. /* System heap to do this stuff, and the smaller I can keep the */
  143. /* chuncks the more likely I am to get them low in the heap, and reduce fragmentation. */
  144.